﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Threading.Tasks;

namespace BhServer
{
    public partial class Form1 : ProgNetComponentsDx.Forms.HideToTrayForm
    {
        ProgNetComponentsDx.Tasks.BaseEventTask t = new ProgNetComponentsDx.Tasks.BaseEventTask();

        public Form1()
        {
            InitializeComponent();
            UpdateServerService.UsersChanged += new EventHandler(UpdateServerService_UsersChanged);
            UpdateServerService.TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();

            t.Name = "Update Server";
            t.TaskPerformed += new ProgNetComponentsDx.Tasks.PerformTaskHandler(t_TaskPerformed);
            t.TaskFinished += new EventHandler(t_TaskFinished);
        }

        void UpdateServerService_UsersChanged(object sender, EventArgs e)
        {
            SetUsers();
        }
        private void SetUsers()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action(SetUsers));
                return;
            }
            listBoxControl1.DataSource = new BindingList<User>(UpdateServerService.GetUsersList());
        }
        void t_TaskFinished(object sender, EventArgs e)
        {
            Append("Finished: " + t.Status);
        }

        void t_TaskPerformed(object sender, ProgNetComponentsDx.Tasks.TaskResultEventArgs e)
        {
            StartService();
        }

        public bool Running;

        private void btnStart_Click(object sender, EventArgs e)
        {
            t.Run();
        }
        
        void host_Opening(object sender, EventArgs e)
        {
            Append("Service opening ... Stand by");
        }
        
        void host_Closed(object sender, EventArgs e)
        {
            Append("Service closed");
        }

        void host_Closing(object sender, EventArgs e)
        {
            Append("Service closing ... stand by");
        }

        void host_Opened(object sender, EventArgs e)
        {
            Append("Service opened.");
            Append("Waiting for clients...");
        }

        private void Append(string str)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action<string>(Append), str);
                return;
            }
            memoEdit1.Text += "\r\n" + str;
            memoEdit1.Select(memoEdit1.Text.Length, 0);
            memoEdit1.ScrollToCaret();
        }
        private void btnStop_Click(object sender, EventArgs e)
        {
            Cancel = true;
        }

        private bool Cancel = false;

        private void StartService()
        {
            Cancel = false;
            Uri baseAddress = new Uri("net.tcp://172.29.3.5:8000/BHServer");
            Uri httpUri = new Uri("http://172.29.3.5:8001/BHServer");

            using (ServiceHost host = new ServiceHost(typeof(UpdateServerService), baseAddress))
            {
                try
                {
                    host.Opening += new EventHandler(host_Opening);
                    host.Opened += new EventHandler(host_Opened);
                    host.Closing += new EventHandler(host_Closing);
                    host.Closed += new EventHandler(host_Closed);
                    var binding = new NetTcpBinding();
                    binding.TransactionFlow = false;
                    binding.Security.Transport.ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign;
                    binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
                    binding.Security.Mode = SecurityMode.None;

                    var updateEndPoint = host.AddServiceEndpoint(typeof(IUpdateServerService), binding, "/Update");
                    var chatEndPoint = host.AddServiceEndpoint(typeof(Comunication.IChatService), binding, "/Chat");
                   
                    ServiceMetadataBehavior metadataBehavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>();

                    if (metadataBehavior == null)
                    {
                        metadataBehavior = new ServiceMetadataBehavior();
                        metadataBehavior.HttpGetUrl = httpUri;
                        metadataBehavior.HttpGetEnabled = true;
                        host.Description.Behaviors.Add(metadataBehavior);
                    }

                    host.Open();
                    while (!Cancel)
                    {
                        System.Threading.Thread.Sleep(50);
                    }
                    host.Close();
                }
                catch (Exception ex)
                {
                    Append(ex.Message);
                }
            }
            Cancel = true;
        }
    }
}
